$trujs
defined in the library<span trujs-init="$trujs.a = 20; $trujs.b = 'Wow!'"></span>
->
TruJS variables, a
and b
, will be created in $trujs
as properties with the initial values.
$trujs.a
-> 20 and $trujs['b']
-> 'Wow!'.
$trujs.
', i.e., properties in $trujs
.<input type='text' trujs-model='x' value='10'>
-> The input value will be modelled by $trujs.x
with the initial value 10.<span trujs-bind='a, b, c'> let d = 10; $trujs.a++; d + ", " + $trujs.b + ", " + $trujs.c </span>
-> The TruJS expression, i.e., the content of <span>...</span>, will be initially evaluated and re-evaluated whenever there is any change in any one of a
, b
, and c
.trujs-bind=''
-> The TruJS expression will be evaluated only once in the beginning.<span trujs-bind=...> let d = 10; $trujs.a++; d + " " + $trujs.b + " " + $trujs.c + " " + $trujs.x; </span>
$trujs
as properties.<input trujs-init='x'>
-> $trujs.x
(or $trujs['x']
) in JavaScript -> multiple <span trujs-bind='x...'>
<script src="https://cs.tru.ca/~mlee/comp4620/Software/TruJS.mo.js"></script> <span trujs-init='$trujs.b = 20'></span> <span trujs-init=''>$trujs.c = 30</span> Case 1: <input type='text' trujs-model='x' value=''><br> Case 2: <input type='text' trujs-model='y' value='TruJS'><br> Case 3: <input type='text' trujs-model='z' value='Fun'><br> <br> <div> Wow!<br><br> Case 1: <span trujs-bind='x'>$trujs.x</span><br> <!-- '$trujs.x' to be evaluated whenever trujs.x is updated. --> Case 2.1: <span trujs-bind='y'></span><br> <!-- no expression --> Case 2.2: <span trujs-bind=''>$trujs.y</span><br> <!-- '$trujs.y' to evaluated only once because trujs-bind does not include y. --> Case 2.3: <span >$trujs.y</span><br> <!-- no evaluation because trujs-bind is not defined. --> Cases 1 and 3: <span trujs-bind='x, z'>let a = 10; $trujs.b++; a + ", " + $trujs.b + ", " + $trujs.c + ", " + $trujs.x + ", " + $trujs.z.toUpperCase()</span><br> </div> <!-- The next code is used just for testing. Without it, Trial 1 would not work, because the TruJS library scans all the elements only with the 'onload' event on 'window'. --> <script> $trujs_init(); </script>
$trujs_init()
, if there is a syntax error, then JavaScript stops.)
$trujs = {}; // models and values; each model --> value; E.g., let model = 'a'; $trujs[model] = 20; $trujs._expressions = {}; // models and expressions; each model --> linear array of objects; // each object, {output:..., expr:...}, includes // output: span element object, and // expr: JS expression that is the content of the span element // E.g., $trujs._expressions[model].push({output:..., expr:...}); // E.g., $trujs['a'] -> 20; // $trujs._expressions['a'] -> [{output:spanobj, expr:'$trujs.a += 20;'}, ...]
trujs-model='m'
.$trujs['m']
with the new value.i = 0
to $trujs._expressions['m'].length - 1
, evaluate $trujs._expressions['m'][i].expr
, and$trujs._expressions['m'][i].output.innerHTML
.
$trujs
$trujs._expressions
$trujs
$trujs._expressions
$trujs._expressions
$trujs._expressions
$trujs
$trujs._expressions
$trujs
, in the TruJS library.<span>
s with trujs-init
and save them in $trujs
.
Let's evaluate the expression in <span>
that uses the two TruJS variables.
How? eval()
<input>
s with trujs-model
and save them in $trujs
.trujs-bind
.
$trujs
, and they will be evaluated by using 'eval()
'.a
and b
are collected in $trujs
in the previous Trial.
m
;$trujs[m]
;$trujs._expressions[m]
,
evaluate expression and update the output;
$trujs._expressions
.trujs-model
.
Test the data-view binding by entering something in the <input>s.
.querySelectorAll()
and use?
document.querySelectorAll()
with attribute selectors$trujs
in trujs-init and in expressions.
How to remove $trujs
from trujs-init and expressions in bind <spans>?
For examples, <span trujs-init='d = 23; e=45'></span>
and
<span trujs-bind = 'd'>a + b + c + d</span>
.function $trujs_update() { // Step1: Select the <span>s that include trujs-init, and initialize TruJS models let init_spans = document.querySelectorAll("span[trujs-init]"); for (let i = 0; i < init_spans.length; i++) { let init_models = init_spans[i].getAttribute("trujs-init").trim().split(/; */); for (let j = 0; j < init_models.length; j++) { if (!init_models[j].startsWith("_expressions")) { let str = "$trujs." + init_models[j].trim(); // Ahha! "$trujs." is attached. eval(str); } } } for (let p in $trujs) { if (p != "_expressions") // i.e., a model $trujs._expressions[p] = []; } }
function $trujs_update()
{
// Step 4. Initial evaluation
// The same idea in Step 5 can be used.
// Step 5. Select the <input>s that include trujs-model, and register 'keyup' event listeners
// In the event listener, update the model, evaluate the related expressions, and update the related s.
let model_inputs = document.querySelectorAll("input[trujs-model]");
for (let i = 0; i < model_inputs.length; i++) {
model_inputs[i].addEventListener('keyup', function() {
let model = this.getAttribute('trujs-model').trim();
$trujs[model] = ????
for (let j = 0; j < $trujs._expressions[model].length; j++) {
let output_span = ????
let expr = "{";
for (let p in $trujs)
if (p != "_expressions")
expr += `let ${p} = '${$trujs[p]}';`; // Ahha! New local variables with all the models in $trujs
expr += $trujs._expressions[model][j].expr; // Ahha! The variables here will use those declared above.
expr += "}";
???? // upate the output with the evaluation result
}
});
}
}